//
//  NvEditCaptionViewController.m
//  NvSellerShow
//
//  Created by Meicam on 2017/4/5.
//  Copyright © 2017年 Meicam. All rights reserved.
//

#import "NvEditCaptionViewController.h"
#import "RectView.h"

@interface NvEditCaptionViewController ()<RectViewDelegate,UICollectionViewDelegateFlowLayout>

@property (nonatomic, assign) BOOL isPlaying;
@property (nonatomic, assign) int64_t playStart;
@property (nonatomic, assign) int64_t playEnd;
@property (nonatomic, strong) NSString *captionId;
@property (nonatomic, strong) NSString *stickerId;
@property (nonatomic, strong) NvsVideoClip * nvsVideoClip;
@property (nonatomic, strong) NSTimer *playbackProgressTimer;
@property (nonatomic, strong) NSMutableArray *assetModelArray;
@property (nonatomic, strong) NSIndexPath *selectedIndexPath;
@property (nonatomic, assign) NSInteger lastBtnTag;
//constraints
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *liveWindowConstraint1v1;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *containerTopConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *liveWindowConstraint16v9;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *liveWindowConstraint9v16;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *liveWindowConstraintLeft;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *liveWindowConstraintTop;
@property (strong, nonatomic) IBOutlet UIView *liveWindowControllView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textFieldConstraintHeight;
@property (weak, nonatomic) IBOutlet UIView *chooseEditStyleView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *collectionHeight;

@property (strong, nonatomic) RectView *rectView;
@property (strong,nonatomic) UIButton *editButton ;

@end

@implementation NvEditCaptionViewController {
    bool _isEditingCaption;
    bool _isEditingSticker;
    bool _isEditing;
    
    CGPoint captionsOffset;
    CGPoint captionsZeroPoint;
    
    CGPoint stickerOffset;
    CGPoint stickerZeroPoint;
    
    CGFloat captionScale;
    CGFloat stickerScale;
    
    NvsTimelineCaption *curCaption;
    NvsTimelineAnimatedSticker * curSticker;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.lastBtnTag = 100;
    [self buildTimeLine];
    _isEditing = YES;
    _isEditingCaption = true;
    _isEditingSticker = false;
    self.edgesForExtendedLayout = UIRectEdgeNone;
    [self.streamingContext connectTimeline:self.timeline withLiveWindow:self.liveWindow];
    self.streamingContext.delegate = self;
    
    if(self.nvsVideoClip) {
        self.playStart = self.nvsVideoClip.inPoint;
        self.playEnd = self.nvsVideoClip.outPoint;
    }
    self.progressSlider.value = 0;
    self.captionId = self.clipModel.captionStyleId.mutableCopy;
    self.stickerId = self.clipModel.stickerPackageId.mutableCopy;
    
    [self registerCaptionStyleCollectionViewCell];
    [self initAssetModelArray];
    [self setupUI];
    [self addNotification];
    [self seekTimeline];
    self.inputTextField.returnKeyType = UIReturnKeyDone;

    //延迟0.15秒执行
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,0.15*NSEC_PER_SEC);
    dispatch_after(time, dispatch_get_main_queue(), ^{
        //设置默认显示字幕，并且默认编辑状态
        [self setCaptionState];
    });
    
    if (IPHONE5) {
        self.collectionHeight.constant = 55.0;
    } else {
        self.collectionHeight.constant = 79.0;
    }
}

-(void)setCaptionState{
    //默认显示字幕
    self.inputTextField.text = @"商品字幕";
    self.progressSlider.value = 0.5;
    [self updateCurLabel];
    [self.streamingContext stop];
    [self addCaption:self.inputTextField.text captionStyleId:self.captionId.copy];
    NvsTimelineCaption *caption =  [_timeline getFirstCaption];
    [caption setCaptionTranslation:captionsOffset];
    [self seekTimeline];
    //默认编辑状态
    [self updateSaveBtn];
}

- (NvsStreamingContext *)streamingContext {
    return [NvsStreamingContext sharedInstanceWithFlags:NvsStreamingContextFlag_Support4KEdit];
}

- (void)fitLiveWindowHeight {
    if(self.editMode == NvSSVideoCreateScaleHorizontal){
        self.liveWindowConstraintTop.constant = (SCREEN_WIDTH-SCREEN_WIDTH*9.0/16.0)/2;
        self.liveWindowConstraint1v1.shouldBeArchived = NO;
        self.liveWindowConstraint1v1.active = NO;
        self.liveWindowConstraint9v16.active = NO;
        [self.view removeConstraints:@[self.liveWindowConstraint1v1,self.liveWindowConstraint9v16]];
        [self.view addConstraints:@[self.liveWindowConstraint16v9,self.liveWindowConstraintLeft,self.liveWindowConstraintTop]];
    } else if (self.editMode == NvSSVideoCreateScaleVertical) {
        self.liveWindowConstraint1v1.active = NO;
        self.liveWindowConstraint16v9.active = NO;
        self.liveWindowConstraintLeft.active = NO;
        [self.view removeConstraints:@[self.liveWindowConstraint16v9,self.liveWindowConstraint1v1,self.liveWindowConstraintLeft]];
        [self.view addConstraints:@[self.liveWindowConstraint9v16,self.liveWindowConstraintTop]];
    } else {
        self.liveWindowConstraint16v9.active = NO;
        self.liveWindowConstraint9v16.active = NO;
        self.liveWindowConstraintTop.active = NO;
        [self.view removeConstraints:@[self.liveWindowConstraint16v9,self.liveWindowConstraint9v16,self.liveWindowConstraintTop]];
        [self.view addConstraints:@[self.liveWindowConstraint1v1,self.liveWindowConstraintLeft]];
    }
    [self.liveWindow addSubview:self.rectView];
}
- (void)setupUI {
    [self fitLiveWindowHeight];
    [self updateCurLabel];
    [self updateDurationLabel];
    [self initNavigationBarView];
    [self initChooseTypeView];
}

- (void)initChooseTypeView {
    self.inputTextField.text = self.clipModel.clipCaption;
    
    CGFloat itemWidth = self.chooseEditStyleView.height_LL - 10;
    NSArray *itemBars = @[@"caption_n",@"sticker_n"];
    NSArray *itemSelectedBars = @[@"caption_s",@"sticker_s"];
    
    for (int i = 0; i < itemBars.count; i++) {
        UIButton *itemBtn = [[UIButton alloc]init];
        itemBtn.frame = CGRectMake((itemWidth + 20)*i + 20, 5, itemWidth, itemWidth);
        [itemBtn setImage:[UIImage imageFromBundle:itemBars[i]] forState:UIControlStateNormal];
        [itemBtn setImage:[UIImage imageFromBundle:itemSelectedBars[i]] forState:UIControlStateSelected];
        
        itemBtn.tag = 100 + i;
        [itemBtn addTarget:self action:@selector(doSelectEvent:) forControlEvents:UIControlEventTouchUpInside];
        
        [self.chooseEditStyleView addSubview:itemBtn];
        
        if (i == 0) {
            UIView *gap = [[UIView alloc]init];
            gap.frame = CGRectMake(CGRectGetMinX(itemBtn.frame), itemBtn.bottom_LL+2, itemWidth,2);
            gap.backgroundColor = UIColorHexRGB(@"#3F80FF");
            gap.tag = 1000;
            [self.chooseEditStyleView addSubview:gap];
        }
    }
}

- (void)initNavigationBarView {
    self.view.backgroundColor = UIColorHexRGB(@"#F5F5F5");
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    UIButton *backBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
    [backBtn setBackgroundImage:[UIImage imageFromBundle:@"back_icon"] forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(cancelBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backBtn];
    
    self.editButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
    [self.editButton setTitle:@"编辑" forState:UIControlStateNormal];
    [self.editButton setTitleColor:UIColorHexRGB(@"#3F80FF") forState:UIControlStateNormal];
    [self.editButton addTarget:self action:@selector(editEvent:) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.editButton];
    
    self.title = @"字幕贴纸";
}

#pragma mark - dealing with TextView and keyboard show and hide
- (void)addNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)info {
    //获取键盘高度，在不同设备上，以及中英文下是不同的
    CGFloat kbHeight = [[info.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
    
    //计算出键盘顶端到inputTextView panel底端的距离(加上自定义的缓冲距离INTERVAL_KEYBOARD)
    CGFloat offset = self.modifuCaptionView.bottom_LL - (self.view.height_LL - kbHeight);
    // 取得键盘的动画时间，这样可以在视图上移的时候更连贯
    double duration = [[info.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    
    //将视图上移计算好的偏移
    if(offset > 0) {
        [UIView animateWithDuration:duration animations:^{
            self.containerTopConstraint.constant -= offset;
        }];
    }
}
- (void)keyboardWillHide:(NSNotification *)info {
    // 键盘动画时间
    double duration = [[info.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    
    //视图下沉恢复原状
    [UIView animateWithDuration:duration animations:^{
        self.containerTopConstraint.constant = 0;
    }];
}

-(void)textFieldDidBeginEditing:(UITextField *)textField{
    textField.text = @"";
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    if (_inputTextField.text.length == 0 || !_inputTextField.text) {
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"请填写商品字幕！" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alertView show];
        return NO;
    }
    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [textField resignFirstResponder];
    if (textField.text) {
        self.progressSlider.value = 0.5;
        [self updateCurLabel];
        [self.streamingContext stop];
        [self addCaption:self.inputTextField.text captionStyleId:self.captionId.copy];
        NvsTimelineCaption *caption =  [_timeline getFirstCaption];
        [caption setCaptionTranslation:captionsOffset];
        [self changeCaptionLocation];
        [self seekTimeline];
    }
}


//hide the keyboard when click other area
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (![touch.view isKindOfClass: [UITextField class]] || ![touch.view isKindOfClass: [UITextView class]]) {
        [self.view endEditing:YES];
    }
}


#pragma mark - Build timeline and caption relative
- (void)buildTimeLine {
    self.timeline = [Utils createTimeLine:self.editMode];
    NvsVideoTrack *videoTrack = [self.timeline appendVideoTrack];
    
    //add clip
    if(self.clipModel.clipType ==  NvClipImage){
        if(self.clipModel.imageDuration.intValue != 0) {
            self.nvsVideoClip = [videoTrack appendClip:self.clipModel.clipPath trimIn:0 trimOut:self.clipModel.imageDuration.intValue * NS_TIME_BASE];
        } else {
            self.nvsVideoClip = [videoTrack appendClip:self.clipModel.clipPath trimIn:0 trimOut:4 * NS_TIME_BASE];
        }
    } else if (self.clipModel.clipType ==  NvClipVideo) {
        if((self.clipModel.triminTimeStamp.longLongValue == 0 && self.clipModel.trimoutTimeStamp.longLongValue == 0)) {
            self.nvsVideoClip = [videoTrack appendClip:self.clipModel.clipPath];
        } else {
            self.nvsVideoClip = [videoTrack appendClip:self.clipModel.clipPath trimIn:self.clipModel.triminTimeStamp.longLongValue trimOut:self.clipModel.trimoutTimeStamp.longLongValue];
        }
        if (self.clipModel.pan && self.clipModel.scan) {
            [self.nvsVideoClip setPan:[self.clipModel.pan floatValue] andScan:[self.clipModel.scan floatValue]];
        }
    }
    
    //apply theme
    if(self.themeUuid) {
        [self.timeline applyTheme:self.themeUuid];
    }
    
    [self addChangesOfModel];
}

- (void)addChangesOfModel {
    //add caption and apply caption style
    if(self.clipModel.clipCaption != nil) {
        [self addCaption:self.clipModel.clipCaption captionStyleId:self.clipModel.captionStyleId];
    }
    
    if (self.clipModel.captionOffset != nil) {
        NvsTimelineCaption *caption = [self getFirstGeneralCaption:self.timeline];
        captionsOffset = CGPointFromString(self.clipModel.captionOffset);
        [caption setCaptionTranslation:captionsOffset];
    }
    
    if (self.clipModel.stickerPackageId) {
        [self.timeline addAnimatedSticker:self.nvsVideoClip.inPoint duration:self.nvsVideoClip.outPoint - self.nvsVideoClip.inPoint animatedStickerPackageId:self.clipModel.stickerPackageId];
    }
    
    if (self.clipModel.stickerOffset != nil) {
        NvsTimelineAnimatedSticker *sticker = [self.timeline getFirstAnimatedSticker];
        stickerOffset = CGPointFromString(self.clipModel.stickerOffset);
        [sticker setTranslation:stickerOffset];
    }
    
    if (self.clipModel.captionScale != nil) {
        NvsTimelineCaption *caption = [self getFirstGeneralCaption:self.timeline];
        CGPoint center = [self getCenterWithArray:[caption getBoundingRectangleVertices]];
        captionScale = self.clipModel.captionScale.floatValue;
        [caption scaleCaption:captionScale anchor:center];
    }
    
    if (self.clipModel.stickerScale != nil) {
        NvsTimelineAnimatedSticker *sticker = [self.timeline getFirstAnimatedSticker];
        stickerScale = self.clipModel.stickerScale.floatValue;
        [sticker setScale:stickerScale];
    }
    
}

- (NvsTimelineCaption *)getFirstGeneralCaption:(NvsTimeline *)timeline {
    NvsTimelineCaption *caption = nil;
    NvsTimelineCaption *tempCaption = [timeline getFirstCaption];
    
    while (tempCaption) {
        if (tempCaption.roleInTheme == NvsRoleInThemeGeneral)
        {
            caption = tempCaption;
            break;
        }
        else
            tempCaption = [self.timeline getNextCaption:tempCaption];
    }
    
    return caption;
}

-(void)addCaption:(NSString *)captionText captionStyleId:(NSString *)captionStyleId {
    NvsTimelineCaption *caption = [self getFirstGeneralCaption:self.timeline];
    if(caption != nil)
        [self.timeline removeCaption:caption];
    
    if(self.nvsVideoClip) {
        if(captionStyleId.length == 0 && [self.timeline getCurrentThemeId])
            captionStyleId = @"theme";
        [self.timeline addCaption:captionText inPoint:self.nvsVideoClip.inPoint duration:self.nvsVideoClip.outPoint - self.nvsVideoClip.inPoint captionStylePackageId:captionStyleId];
    }
}

- (void)clearTimeLine {
    if (self.timeline)
        [self.streamingContext removeTimeline:self.timeline];
    self.streamingContext = nil;
}


#pragma mark - captionStyle CollectionView

static NSString* captionStyleCellIdentifier = @"NvCapationStyleCell";

- (void)registerCaptionStyleCollectionViewCell {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"NvSellerResource" ofType:@"bundle"];
    NSBundle *myBundle = [NSBundle bundleWithPath:path];
    [self.collectionView registerNib:[UINib nibWithNibName:captionStyleCellIdentifier bundle:myBundle]  forCellWithReuseIdentifier:captionStyleCellIdentifier];
}

- (void)initAssetModelArray {
    self.assetModelArray = [NSMutableArray array];
    
    if (_isEditingCaption) {
        //add null captionstyle
        NvAssetModel * noneCaptionStyle = [[NvAssetModel alloc] initWithPath:@"" andId:@"" andType:NvAssetCaptionStyle];
        noneCaptionStyle.displayName = @"默认";
        [self.assetModelArray addObject:noneCaptionStyle];
        
        [self.assetModelArray addObjectsFromArray:[[NvAssetManager new] getAssetsWithAssetType:NvAssetCaptionStyle]];
        
        //to do: set curent captionStyle
        if(self.captionId.length == 0) {
            self.selectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        } else {
            NvAssetModel *assetModel;
            for (NSInteger i = 0; i < self.assetModelArray.count; i++) {
                assetModel = self.assetModelArray[i];
                if([self.captionId isEqualToString:assetModel.assetId] == YES) {
                    self.selectedIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
                    break;
                }
            }
        }
    }
    if (_isEditingSticker) {
        //add null captionstyle
        NvAssetModel * noneCaptionStyle = [[NvAssetModel alloc] initWithPath:@"" andId:@"" andType:NvAssetAnimatedSticker];
        noneCaptionStyle.displayName = @"无";
        [self.assetModelArray addObject:noneCaptionStyle];
        
        [self.assetModelArray addObjectsFromArray:[[NvAssetManager new] getAssetsWithAssetType:NvAssetAnimatedSticker]];
        
        //to do: set curent captionStyle
        if(self.stickerId.length == 0) {
            self.selectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        } else {
            NvAssetModel *assetModel;
            for (NSInteger i = 0; i < self.assetModelArray.count; i++) {
                assetModel = self.assetModelArray[i];
                if([self.stickerId isEqualToString:assetModel.assetId] == YES) {
                    self.selectedIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
                    break;
                }
            }
        }
    }
}

#pragma mark - implement collectionView delegate

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (IPHONE5) {
        return CGSizeMake(50, 50);
    } else {
        return CGSizeMake(79, 79);
    }
}

//返回section中的cell个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.assetModelArray.count;
}

//返回cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    NvCapationStyleCell * cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:captionStyleCellIdentifier forIndexPath:indexPath];
    NvAssetModel *model = self.assetModelArray[indexPath.row];
    UIImage *thumb;
    if([model.assetId isEqualToString:@""]) {
        if (_isEditingCaption) {
            thumb = [UIImage imageFromBundle:@"Rectangle"];
        } else {
            thumb = [UIImage imageFromBundle:@"noSticker"];
        }
    } else {
        thumb = [UIImage imageWithContentsOfFile:model.imageCoverPath];
    }
    cell.coverImageView.contentMode = UIViewContentModeScaleAspectFit;
    cell.coverImageView.image = thumb;
    cell.displayLabel.text = model.displayName;
    cell.selected = self.selectedIndexPath ? ([self.selectedIndexPath compare:indexPath] == NSOrderedSame) : NO;
    return cell;
}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    if([self.selectedIndexPath isEqual:indexPath])
        return;
    if(self.selectedIndexPath){
        [self cellAtIndexPath:self.selectedIndexPath].selected = NO;
    }
    self.selectedIndexPath = indexPath;
    [self cellAtIndexPath:self.selectedIndexPath].selected = YES;
    [self installCurrentPackage];
    //编辑字幕
    if (_isEditingCaption ) {
        [self applyCaption];
        curCaption = [_timeline getFirstCaption];
        captionsZeroPoint = [self getCenterWithArray:[curCaption getBoundingRectangleVertices]];
        [self updateCaptionView:curCaption];
    }
    //编辑贴纸
    if (_isEditingSticker) {
        [self applySticker];
        curSticker = [_timeline getFirstAnimatedSticker];
        [curSticker setTranslation:stickerOffset];
        [self updateStickerView:curSticker];
        
        _isEditing = YES;
        [self updateSaveBtn];
        [self.streamingContext seekTimeline:self.timeline timestamp:self.playStart videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:0];
        self.progressSlider.value = 0;
        [self updateCurLabel];
        [self play];
    }
    [self seekTimeline];
}

- (NvCapationStyleCell *)cellAtIndexPath:(NSIndexPath *)indexPath {
    return (NvCapationStyleCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
}

#pragma mark - implement apply captionStyle
- (NvAssetModel *)getAssetModelWithIndexPath:(NSIndexPath *)indexPath {
    return (NvAssetModel *)self.assetModelArray[indexPath.row];
}

- (void)applySticker{
    //remove current sticker
    NvsTimelineAnimatedSticker *sticker = [self.timeline getFirstAnimatedSticker];
    if(sticker != nil)
        [self.timeline removeAnimatedSticker:sticker];
    //none sticker
    if(self.selectedIndexPath.item == 0) {
        self.stickerId = @"";
    } else {
        
        [self.timeline addAnimatedSticker:0 duration:self.timeline.duration animatedStickerPackageId:self.stickerId.copy];
    }
}

- (void)applyCaption {
    NvsTimelineCaption *caption = [self.timeline getFirstCaption];
    if (caption != nil) {
        [self.timeline removeCaption:caption];
    }
    
    if (self.selectedIndexPath.item == 0) {
        self.captionId = @"".mutableCopy;
    } else {
        
    }
    [self addCaption:self.inputTextField.text captionStyleId:self.captionId.copy];
}

- (void)installCurrentPackage {
    NSMutableString *packageId;
    if (_isEditingCaption) {
        packageId = self.captionId.mutableCopy;
    }
    if (_isEditingSticker) {
        packageId = self.stickerId.mutableCopy;
    }
    
    NvAssetModel * waitingInstallModel = [self getAssetModelWithIndexPath:self.selectedIndexPath];
    if([waitingInstallModel.assetId isEqualToString:@""] == YES) {
        packageId = [@"" mutableCopy];
        return;
    }
    
    NvsAssetPackageManagerError  error = NvsAssetPackageManagerError_NoError;
    NSString *waitingInstallPackagePath = waitingInstallModel.assetPackagePath;
    NSString *waitingInstallPackageId = waitingInstallModel.assetId;
    
    NvsAssetPackageStatus packageStatus = [self.streamingContext.assetPackageManager getAssetPackageStatus:waitingInstallPackageId type:(NvsAssetPackageType)waitingInstallModel.type];
    
    //package is already installed
    if(packageStatus != NvsAssetPackageStatus_NotInstalled) {
        NSInteger installedVersion = [self.streamingContext.assetPackageManager getAssetPackageVersion:waitingInstallPackageId type:(NvsAssetPackageType)waitingInstallModel.type];
        //package need to update
        if(waitingInstallModel.version > installedVersion) {
            error = [self.streamingContext.assetPackageManager upgradeAssetPackage:waitingInstallPackagePath license:waitingInstallModel.licensePath type:(NvsAssetPackageType)waitingInstallModel.type sync:YES assetPackageId:packageId];
        }
        else {
            packageId = waitingInstallPackageId.mutableCopy;
        }
    }
    //package need install
    else {
        error = [self.streamingContext.assetPackageManager installAssetPackage: waitingInstallPackagePath license:waitingInstallModel.licensePath type:(NvsAssetPackageType)waitingInstallModel.type sync:YES assetPackageId:packageId];
    }
    
    if(error == NvsAssetPackageManagerError_NoError|| error == NvsAssetPackageManagerError_AlreadyInstalled)
        packageId = [self getAssetModelWithIndexPath:self.selectedIndexPath].assetId.mutableCopy;
    NSLog(@"installing sticker Package: %d %@ \n %@ \n %@ \n%@", error, waitingInstallPackagePath, packageId, [self getAssetModelWithIndexPath:self.selectedIndexPath].assetId,waitingInstallModel.licensePath);
    if (_isEditingCaption) {
        self.captionId = packageId.mutableCopy;
    }
    if (_isEditingSticker) {
        self.stickerId = packageId.mutableCopy;
    }
}

#pragma mark - implement NvsLivewindow Player
- (void)updateCurLabel {
    self.curLabel.text = [Utils stringWithTime:self.progressSlider.value * (self.playEnd - self.playStart)/NS_TIME_BASE];
}

- (void)updateDurationLabel {
    self.durationLabel.text = [Utils stringWithTime:(self.playEnd - self.playStart)/NS_TIME_BASE];
}

- (void)updatePlayBtnState {
    [self.playBtn setImage: self.isPlaying? [UIImage imageFromBundle:@"player_stop"]: [UIImage imageFromBundle:@"player_play"]  forState:UIControlStateNormal];
}

- (void)seekTimeline {
    if(self.isPlaying) {
        [self stop];
    }
    
    self.rectView.frame = self.liveWindow.bounds;
    
    int flag = 0;
    int64_t seekPos = self.playStart + self.progressSlider.value * (self.playEnd - self.playStart);
    [self.streamingContext seekTimeline:self.timeline timestamp:seekPos videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:flag];
}

- (void)startPlaybackProgressTimer {
    NSTimeInterval timeInterval = 0.1;
    self.playbackProgressTimer = [NSTimer timerWithTimeInterval:timeInterval target:self selector:@selector(handleProgressTimer:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop]addTimer:self.playbackProgressTimer forMode:NSRunLoopCommonModes];
}

- (void)handleProgressTimer:(NSTimer *)timer {
    self.progressSlider.value = ([self.streamingContext getTimelineCurrentPosition:self.timeline] - self.playStart) * 1.0/(self.playEnd - self.playStart);
    [self updateCurLabel];
}

- (void)play{
    int64_t startTime = self.playStart + self.progressSlider.value * (self.playEnd - self.playStart);
    int64_t endTime = self.playEnd;
    [self startPlaybackProgressTimer];
    
    [self.streamingContext playbackTimeline:self.timeline startTime:startTime endTime:endTime videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize preload:YES flags:0];
    self.isPlaying = YES;
    [self updatePlayBtnState];
}

- (void)stop {
    [self.streamingContext stop];
    [self updateStopState];
}

- (void)updateStopState {
    [self.playbackProgressTimer invalidate];
    self.isPlaying = NO;
    [self updatePlayBtnState];
}

- (void)playAndStop {
    if(self.isPlaying)
        [self stop];
    else
        [self play];
}

#pragma mark - StreamingContext playing delegate
- (void)didPlaybackEOF:(NvsTimeline *)timeline {
    if(timeline == self.timeline) {
        [self.streamingContext seekTimeline:self.timeline timestamp:self.playStart videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:0];
        self.progressSlider.value = 0;
        [self updateCurLabel];
    }
}

- (void)didPlaybackStopped:(NvsTimeline *)timeline {
    if(timeline == self.timeline) {
        [self updateStopState];
    }
}

#pragma mark - implement button response

- (IBAction)playBtnPressed:(id)sender {
    [self playAndStop];
}

- (IBAction)progressSliderValueChanged:(id)sender {
    [self seekTimeline];
    [self updateCurLabel];
}

- (IBAction)cancelBtnPressed:(id)sender {
    [self.streamingContext stop];
    [self clearTimeLine];
    [self.navigationController popViewControllerAnimated:YES];
}

- (IBAction)okBtnPressed:(id)sender {
    [self.streamingContext stop];
    [self clearTimeLine];
    if(self.delegate != nil && [self.delegate respondsToSelector:@selector(nvEditCaptionViewController:didFinishSetCaption:withCaptionStyleId:captionOffset:didFinishSetStickerId:stickerOffset:captionScale:stickerScale:)] ==YES) {
        [self.delegate nvEditCaptionViewController:self didFinishSetCaption:self.inputTextField.text withCaptionStyleId:self.captionId.copy captionOffset:NSStringFromCGPoint(captionsOffset) didFinishSetStickerId:self.stickerId stickerOffset:NSStringFromCGPoint(stickerOffset) captionScale:captionScale stickerScale:stickerScale];
    }
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark Dealoc
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark MoveLocationOfCaption
- (void)doSelectEvent:(UIButton *)sender {
    if (_isEditing) {
        return;
    }
    UIView *line = [self.chooseEditStyleView viewWithTag:1000];
    [self.view layoutIfNeeded];
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    if (sender.tag != self.lastBtnTag) {
        UIButton *button = [self.chooseEditStyleView viewWithTag:self.lastBtnTag];
        [button setSelected:NO];
        self.lastBtnTag = sender.tag;
        
        //VALUE 用的是中心点的坐标(MID)
        NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(button.frame), CGRectGetMidY(line.frame))];
        
        NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(sender.frame),  CGRectGetMidY(line.frame))];
        animation.values = @[value1,value2];
        animation.repeatCount = 0;
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
        animation.duration = 0.2f;
        animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [line.layer addAnimation:animation forKey:@"path"];
    }
    
    if (!sender.selected) {
        sender.selected = YES;
    }
    if (sender.tag == 100) {
        _isEditingCaption = true;
        _isEditingSticker = false;
        self.textFieldConstraintHeight.constant = 30;
        /***/
    } else {
        _isEditingSticker = true;
        _isEditingCaption = false;
        self.textFieldConstraintHeight.constant = 0;
        /***/
    }
    [self initAssetModelArray];
    [self.collectionView reloadData];
    [self installCurrentPackage];
    //停止播放
    [self.streamingContext seekTimeline:self.timeline timestamp:self.playStart videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:0];
    [self updateCurLabel];
    if (_isEditingSticker) {
        [self applySticker];
    } else {
        [self applyCaption];
    }
    _isEditing = YES;
    [self updateSaveBtn];
}


- (void)editEvent:(UIButton *)sender {
    if (_inputTextField.text.length == 0 && _isEditingCaption) {
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"请填写商品字幕！" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alertView show];
        return;
    }
    _isEditing = !_isEditing;
    
    [self updateSaveBtn];
}

- (void)updateSaveBtn {

    if (_isEditingSticker && self.selectedIndexPath.item == 0) {
        _isEditing = NO;
    }
    self.progressSlider.value = 0.5;
    [self updateCurLabel];
    if (_isEditing) {
        [self.editButton setTitle:@"保存" forState:UIControlStateNormal];
        [self.liveWindowControllView setHidden:YES];
        if (_isEditingCaption) {
            [self changeCaptionLocation];
        } else {
            [self changeStickerLocation];
        }
    } else {
        [self.editButton setTitle:@"编辑" forState:UIControlStateNormal];
        [self.liveWindowControllView setHidden:NO];
        self.inputTextField.userInteractionEnabled = YES;
        
        [self.streamingContext seekTimeline:self.timeline timestamp:self.playStart videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:0];
        self.progressSlider.value = 0;
        [self updateCurLabel];
        [self play];
        
        if (_isEditingCaption) {
            [self editFinishCaption];
        } else {
            [self editFinishSticker];
        }
    }
}

- (void)changeCaptionLocation {
    curCaption = [_timeline getFirstCaption];
    
    [self showCaptionDragView];
    [self updateCaptionView:curCaption];
}

- (void)changeStickerLocation {
    curSticker = [_timeline getFirstAnimatedSticker];

    [self showStickerDragView];
    [self updateStickerView:curSticker];
}

- (void)editFinishCaption {
    self.rectView.hidden = YES;
}

- (void)editFinishSticker {
    self.rectView.hidden = YES;
}

- (void)deleteSticker {
    // 删除动画贴纸
    if (curSticker != nil){
        curSticker = [_timeline removeAnimatedSticker:curSticker];

        if (curSticker != nil) {
            [self updateStickerView:curSticker];
            [self showStickerDragView];
        }
        _stickerId = @"";
    }
    [self editFinishSticker];
    
    [self seekTimeline];
}


- (RectView *)rectView {
    if (!_rectView) {
        _rectView = [[RectView alloc] initWithFrame:_liveWindow.bounds];
        _rectView.videoscale = self.editMode;
        _rectView.delegate = self;
        _rectView.hidden = YES;
    }
    return _rectView;
}

- (void)rectView:(RectView *)rectView scale:(float)scale {
    if (_isEditingCaption) {
        NSArray *array = [curCaption getBoundingRectangleVertices];
        CGPoint center = [self getCenterWithArray:array];
        captionScale *= scale;
        [curCaption scaleCaption:scale anchor:center];
        [self updateCaptionView:curCaption];
    } else {
        NSArray *array = [curSticker getBoundingRectangleVertices];
        CGPoint center = [self getCenterWithArray:array];
        stickerScale *= scale;
        [curSticker scaleAnimatedSticker:scale anchor:center];
        [self updateStickerView:curSticker];
    }
}

//- (void)rectView:(RectView*)rectView rotate:(float)rotate scale:(float)scale {
//    if (_isEditingCaption) {
//        NSArray *array = [curCaption getBoundingRectangleVertices];
//        CGPoint center = [self getCenterWithArray:array];
//
//        [curCaption scaleCaption:scale anchor:center];
//        [curCaption rotateCaption:rotate anchor:center];
//        [self updateCaptionView:curCaption];
//    } else {
//
//        NSArray *array = [curSticker getBoundingRectangleVertices];
//        CGPoint center = [self getCenterWithArray:array];
//
//        [curSticker scaleAnimatedSticker:scale anchor:center];
//        [curSticker rotateAnimatedSticker:rotate anchor:center];
//        [self updateStickerView:curSticker];
//    }
//}

- (void)rectView:(RectView*)rectView close:(UIButton*)closeButton {
    _isEditing = NO;
    self.selectedIndexPath = [NSIndexPath indexPathForItem:0 inSection:0];
    [self.collectionView selectItemAtIndexPath:self.selectedIndexPath animated:YES scrollPosition:UICollectionViewScrollPositionLeft];
    [self updateSaveBtn];
    [self.collectionView reloadData];
    if (_isEditingCaption) {
        [self deleteCaption];
    } else {
        [self deleteSticker];
    }
}

#pragma mark EditCaption

- (void)deleteCaption {
    // 删除字幕
    if (curCaption != nil){
        curCaption = [_timeline removeCaption:curCaption];
        
        if(curCaption != nil){
            [self updateCaptionView:curCaption];
            [self showCaptionDragView];
        }
        
    }
    [self editFinishCaption];
    
    [self seekTimeline];
}

- (void)showCaptionDragView {
    int64_t inPoint = [curCaption inPoint];
    int64_t outPoint = [curCaption outPoint];
    int64_t currentTime = 3;
    if(currentTime>=inPoint && currentTime<=outPoint) {
        self.rectView.hidden = false;
    } else {
        if(_isEditingCaption) {
            self.rectView.hidden = true;
        }
    }
}

- (void)showStickerDragView {
    int64_t inPoint = [curSticker inPoint];
    int64_t outPoint = [curSticker outPoint];
    int64_t currentTime = 2;
    if(currentTime>=inPoint && currentTime<=outPoint) {
        self.rectView.hidden = false;
    } else {
        if(_isEditingSticker) {
            self.rectView.hidden = true;
        }
    }
}

- (void)updateCaptionView: (NvsTimelineCaption *)caption {
    //获取到当前字幕矩形坐标
    NSArray *array = [caption getBoundingRectangleVertices];
    NSValue *leftTopValue = array[0];
    NSValue *leftBottomValue = array[1];
    NSValue *rightBottomValue = array[2];
    NSValue *rightTopValue = array[3];
    CGPoint topLeftCorner = [leftTopValue CGPointValue];
    CGPoint bottomLeftCorner = [leftBottomValue CGPointValue];
    CGPoint rightBottomCorner = [rightBottomValue CGPointValue];
    CGPoint rightTopCorner = [rightTopValue CGPointValue];
    
    //时间线坐标转换成视图坐标
    topLeftCorner = [_liveWindow mapCanonicalToView:topLeftCorner];
    rightBottomCorner = [_liveWindow mapCanonicalToView:rightBottomCorner];
    bottomLeftCorner = [_liveWindow mapCanonicalToView:bottomLeftCorner];
    rightTopCorner = [_liveWindow mapCanonicalToView:rightTopCorner];

//    if (topLeftCorner.x < 20) {
//        topLeftCorner.x = 20;
//        bottomLeftCorner.x = 20;
//    }
//    if (topLeftCorner.y < 20) {
//        topLeftCorner.y = 20;
//        rightTopCorner.y = 20;
//    }
//    if (rightBottomCorner.x > self.liveWindow.right_LL-30) {
//        rightBottomCorner.x = self.liveWindow.right_LL-30;
//        rightTopCorner.x = self.liveWindow.right_LL-30;
//    }
//    if (rightBottomCorner.y > self.liveWindow.bottom_LL-30) {
//        rightBottomCorner.y = self.liveWindow.bottom_LL-30;
//        bottomLeftCorner.y = self.liveWindow.bottom_LL-30;
//    }
    [self.rectView setPoints:@[[NSValue valueWithCGPoint:[_liveWindow convertPoint:topLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:bottomLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightBottomCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightTopCorner toView:self.rectView]]]];
    
    [self seekTimeline];
}

- (void)updateStickerView: (NvsTimelineAnimatedSticker *)sticker {
    //获取贴图的四角时间线坐标
    NSArray *array = [sticker getBoundingRectangleVertices];
    NSValue *leftTopValue = array[0];
    NSValue *leftBottomValue = array[1];
    NSValue *rightBottomValue = array[2];
    NSValue *rightTopValue = array[3];
    CGPoint topLeftCorner = [leftTopValue CGPointValue];
    CGPoint bottomLeftCorner = [leftBottomValue CGPointValue];
    CGPoint rightBottomCorner = [rightBottomValue CGPointValue];
    CGPoint rightTopCorner = [rightTopValue CGPointValue];

    //将贴图四角时间线坐标转换成视图坐标
    topLeftCorner = [_liveWindow mapCanonicalToView:topLeftCorner];
    rightBottomCorner = [_liveWindow mapCanonicalToView:rightBottomCorner];
    bottomLeftCorner = [_liveWindow mapCanonicalToView:bottomLeftCorner];
    rightTopCorner = [_liveWindow mapCanonicalToView:rightTopCorner];
    
    [self.rectView setPoints:@[[NSValue valueWithCGPoint:[_liveWindow convertPoint:topLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:bottomLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightBottomCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightTopCorner toView:self.rectView]]]];
    
    [self seekTimeline];
}

- (CGPoint)getCenterWithArray:(NSArray*)array {
    NSValue *leftTopValue = array[0];
    NSValue *rightBottomValue = array[2];
    CGPoint topLeftCorner = [leftTopValue CGPointValue];
    CGPoint rightBottomCorner = [rightBottomValue CGPointValue];
    return CGPointMake((topLeftCorner.x+rightBottomCorner.x)/2, (topLeftCorner.y+rightBottomCorner.y)/2);
}

#pragma mark - RectViewDelegate
- (void)rectView:(RectView*)rectView currentPoint:(CGPoint)currentPoint previousPoint:(CGPoint)previousPoint {
    //视图坐标转换成时间线坐标
    CGPoint p1 = [_liveWindow mapViewToCanonical:currentPoint];
    CGPoint p2 = [_liveWindow mapViewToCanonical:previousPoint];
    CGPoint newPoint = CGPointMake(p1.x-p2.x, p1.y-p2.y);
    dispatch_async(dispatch_get_main_queue(), ^{
        if (_isEditingCaption) {
            //偏移字幕
            [curCaption translateCaption:newPoint];
            //记录字幕偏移量
            captionsOffset = CGPointMake(captionsOffset.x+newPoint.x, captionsOffset.y+newPoint.y);
            [self updateCaptionView:curCaption];
        }
        else {
            //偏移贴纸
            [curSticker translateAnimatedSticker:newPoint];
            //记录贴纸偏移量
            stickerOffset = CGPointMake(stickerOffset.x+newPoint.x, stickerOffset.y+newPoint.y);
            
            [self updateStickerView:curSticker];
        }
    });
}

//开始编辑
- (void)rectView:(RectView*)rectView touchBeganPoint:(CGPoint)point{
    if(_isEditingCaption){
        
        [self pointIsInRectEditCaption:point];
    } else if(_isEditingSticker){
        
        [self pointIsInRectEditSticker:point];
    }
}

//判断点是否在字幕矩形内
- (BOOL)pointIsInRectEditCaption:(CGPoint) point{
    //获取到字幕的原始包围举行框的四角坐标
    NSArray *array = [curCaption getBoundingRectangleVertices];
    NSValue *leftTopValue = array[0];
    NSValue *leftBottomValue = array[1];
    NSValue *rightBottomValue = array[2];
    NSValue *rightTopValue = array[3];
    CGPoint topLeftCorner = [leftTopValue CGPointValue];
    CGPoint bottomLeftCorner = [leftBottomValue CGPointValue];
    CGPoint rightBottomCorner = [rightBottomValue CGPointValue];
    CGPoint rightTopCorner = [rightTopValue CGPointValue];
    
    //将获取到的时间线坐标转换成视图坐标
    topLeftCorner = [_liveWindow mapCanonicalToView:topLeftCorner];
    rightBottomCorner = [_liveWindow mapCanonicalToView:rightBottomCorner];
    bottomLeftCorner = [_liveWindow mapCanonicalToView:bottomLeftCorner];
    rightTopCorner = [_liveWindow mapCanonicalToView:rightTopCorner];
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGMutablePathRef pathRef=CGPathCreateMutable();
    CGPathMoveToPoint(pathRef, NULL, topLeftCorner.x, topLeftCorner.y);
    CGPathAddLineToPoint(pathRef, NULL, bottomLeftCorner.x, bottomLeftCorner.y);
    CGPathAddLineToPoint(pathRef, NULL, rightBottomCorner.x, rightBottomCorner.y);
    CGPathAddLineToPoint(pathRef, NULL, rightTopCorner.x, rightTopCorner.y);
    CGPathCloseSubpath(pathRef);
    CGContextAddPath(ctx, pathRef);
    bool isIn = CGPathContainsPoint(pathRef, nil, point, false);
    
    //判断点是否在Rect里面，在的话重新绘制
    if(isIn){
        [self.rectView setPoints:@[[NSValue valueWithCGPoint:[_liveWindow convertPoint:topLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:bottomLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightBottomCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightTopCorner toView:self.rectView]]]];
        
        return isIn;
    }
    
    return false;
}

//判断点是否在贴纸矩形内
- (BOOL)pointIsInRectEditSticker:(CGPoint) point{
    NSArray *array = [curSticker getBoundingRectangleVertices];
    NSValue *leftTopValue = array[0];
    NSValue *leftBottomValue = array[1];
    NSValue *rightBottomValue = array[2];
    NSValue *rightTopValue = array[3];
    CGPoint topLeftCorner = [leftTopValue CGPointValue];
    CGPoint bottomLeftCorner = [leftBottomValue CGPointValue];
    CGPoint rightBottomCorner = [rightBottomValue CGPointValue];
    CGPoint rightTopCorner = [rightTopValue CGPointValue];
    
    topLeftCorner = [_liveWindow mapCanonicalToView:topLeftCorner];
    rightBottomCorner = [_liveWindow mapCanonicalToView:rightBottomCorner];
    bottomLeftCorner = [_liveWindow mapCanonicalToView:bottomLeftCorner];
    rightTopCorner = [_liveWindow mapCanonicalToView:rightTopCorner];
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGMutablePathRef pathRef=CGPathCreateMutable();
    CGPathMoveToPoint(pathRef, NULL, topLeftCorner.x, topLeftCorner.y);
    CGPathAddLineToPoint(pathRef, NULL, bottomLeftCorner.x, bottomLeftCorner.y);
    CGPathAddLineToPoint(pathRef, NULL, rightBottomCorner.x, rightBottomCorner.y);
    CGPathAddLineToPoint(pathRef, NULL, rightTopCorner.x, rightTopCorner.y);
    CGPathCloseSubpath(pathRef);
    CGContextAddPath(ctx, pathRef);
    bool isIn = CGPathContainsPoint(pathRef, nil, point, false);
    
    if(isIn){
        [self.rectView setPoints:@[[NSValue valueWithCGPoint:[_liveWindow convertPoint:topLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:bottomLeftCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightBottomCorner toView:self.rectView]],[NSValue valueWithCGPoint:[_liveWindow convertPoint:rightTopCorner toView:self.rectView]]]];

        return isIn;
    }
    return false;
}

@end
